// 函数演示文件: functions_demo.rs
// 本文件演示Rust中函数的定义、参数、返回值等相关知识

// 1. 基本函数定义与调用
// fn 函数名(参数列表) -> 返回类型 { 函数体 }
fn greet() {
    println!("Hello, Rust functions!");
}

// 2. 带有参数的函数
// 参数格式: 参数名: 参数类型
fn add(a: i32, b: i32) -> i32 {
    // Rust中，函数的最后一个表达式的结果会自动作为返回值
    // 不需要使用return关键字，除非需要提前返回
    a + b
}

// 3. 带有多个参数和返回值的函数
fn calculate(a: i32, b: i32) -> (i32, i32, i32) {
    let sum = a + b;
    let difference = a - b;
    let product = a * b;
    // 返回元组
    (sum, difference, product)
}

// 4. 带有默认参数行为的函数
// Rust没有内置的默认参数，但可以通过函数重载或 Option 类型模拟
fn greet_person(name: &str, title: Option<&str>) {
    match title {
        Some(t) => println!("Hello, {} {}", t, name),
        None => println!("Hello, {}", name),
    }
}

// 5. 可变参数函数
// 使用std::vec::Vec作为参数来模拟可变参数
fn sum_all(numbers: &[i32]) -> i32 {
    let mut total = 0;
    for &num in numbers {
        total += num;
    }
    total
}

// 6. 函数作为参数
fn apply_operation(a: i32, b: i32, operation: fn(i32, i32) -> i32) -> i32 {
    operation(a, b)
}

// 7. 闭包作为参数
fn calculate_with_closure<F>(a: i32, b: i32, f: F) -> i32
where
    F: Fn(i32, i32) -> i32,
{
    f(a, b)
}

// 8. 返回函数的函数
fn create_multiplier(factor: i32) -> impl Fn(i32) -> i32 {
    move |x| x * factor
}

// 主函数，用于演示上述函数
pub fn main() {
    // 1. 调用基本函数
    greet();

    // 2. 调用带参数和返回值的函数
    let result = add(5, 3);
    println!("5 + 3 = {}", result);

    // 3. 调用返回多个值的函数
    let (sum, diff, product) = calculate(10, 4);
    println!("10 + 4 = {}", sum);
    println!("10 - 4 = {}", diff);
    println!("10 * 4 = {}", product);

    // 4. 调用模拟默认参数的函数
    greet_person("Alice", None);
    greet_person("Bob", Some("Mr."));

    // 5. 调用可变参数函数
    let numbers = [1, 2, 3, 4, 5];
    println!("Sum of {:?} = {}", numbers, sum_all(&numbers));

    // 6. 传递函数作为参数
    let multiply = |x: i32, y: i32| x * y;
    let op_result = apply_operation(6, 7, add);
    println!("6 + 7 = {}", op_result);

    // 7. 使用闭包作为参数
    let closure_result = calculate_with_closure(8, 2, |x, y| x / y);
    println!("8 / 2 = {}", closure_result);

    // 8. 使用返回的函数
    let double = create_multiplier(2);
    let triple = create_multiplier(3);
    println!("Double of 5 = {}", double(5));
    println!("Triple of 5 = {}", triple(5));
}